---
description: Компонент для создания элементов форм с поддержкой заголовка, подсказки и статуса валидации.
---

<Overview group="forms">

# FormItem [tag:component]

Компонент для создания элементов форм с поддержкой заголовка, подсказки и статуса валидации.
Позволяет создавать структурированные и доступные формы с единым стилем оформления.
Рекомендуется оборачивать в компонент все поля, кроме [`Radio`](/components/radio) и [`Checkbox`](/components/checkbox), если для
них в дизайне не предусмотрены заголовки и иные описательные элементы.

</Overview>

<Playground>
  ```jsx
  <FormItem htmlFor="email" top="E-mail">
    <Input type="email" id="email" name="email" />
  </FormItem>
  ```
</Playground>

## Структура компонента

`FormItem` состоит из трёх основных частей:

- `top` — заголовок элемента формы;
- `children` — основной контент (поле ввода);
- `bottom` — подсказка или сообщение о статусе валидации.

<Playground>
  ```jsx
  <FormItem
    htmlFor="email"
    top="E-mail"
    bottom="Мы не передаём вашу почту третьим лицам"
    bottomId="email-type"
  >
    <Input type="email" id="email" name="email" aria-labelledby="email-type" />
  </FormItem>
  ```
</Playground>

### Подкомпоненты

Иногда шапка у поля может быть составной, то есть содержать несколько отдельных компонентов для сегментирования
представленной информации. В таком случае воспользуйтесь подкомпонентами, которые позволят вам собрать необходимый
заголовок самостоятельно и более гибко управлять передаваемыми в компоненты свойствами (например, для `a11y`).

- `<FormItem.Top>` служит оберткой для составной шапки поля, отвечая за выравнивание контента и расстановку отступов;
- `<FormItem.TopLabel>` отвечает за отрисовку заголовка поля. По умолчанию компонент представлен тегом `label`,
  если передано свойство `htmlFor`. Можно переопределить через свойство `Component`;
- `<FormItem.TopAside>` отвечает за отрисовку дополнительного контента справа от заголовка поля.

<Playground>
  ```jsx
  <FormItem
    top={
      <FormItem.Top>
        <FormItem.TopLabel htmlFor="about">Дополнительная информация</FormItem.TopLabel>
        <FormItem.TopAside>0/100</FormItem.TopAside>
      </FormItem.Top>
    }
  >
    <Textarea id="about" name="about" />
  </FormItem>
  ```
</Playground>

## Состояния

#### `disabled`

Свойство `disabled` блокирует взаимодействие с компонентом и добавляет визуальную индикацию недоступности.

> Свойство `disabled` необходимо передавать и компоненту `FormItem`, и вложенному в него полю, потому что
> свойство влияет на разные части компонентов. Например, недоступные поля ввода по умолчанию нельзя [удалить](#removable).

<Playground>
  ```jsx
  <FormItem htmlFor="email" top="E-mail" disabled>
    <Input type="email" id="email" name="email" disabled />
  </FormItem>
  ```
</Playground>

## Валидация

Задаётся свойством `status`.

- `"default"` - обычное состояние компонента (по умолчанию);
- `"error"` - состояние ошибки, используйте данное значение, чтобы сообщить пользователю о некорректно введённых данных;
- `"valid"` - состояние успешной валидации, используйте для индикации прошедшей проверки или при исправлении ошибки.

Если вы используете значения `"error"` (реже `"valid"`), старайтесь сопровождать состояние поясняющим сообщением, например,
используя свойство `bottom`.

<Playground direction="column">
  ```jsx
  <FormItem
    htmlFor="email"
    top="E-mail"
    status="error"
    bottom="Пожалуйста, введите e-mail"
    bottomId="email-type"
    required
    noPadding
  >
    <Input aria-labelledby="email-type" id="email" type="email" name="email" required />
  </FormItem>
  <FormItem htmlFor="text" top="Описание" status="valid" noPadding>
    <Input id="text" name="text" />
  </FormItem>
  ```
</Playground>

## Обязательность поля

Свойство `required` позволяет пометить поле как обязательное для заполнения.

> Обратите внимание, что данное свойство отвечает только за визуальную составляющую.
> На само поле, которое обёрнуто в `FormItem`, следует дополнительно передавать свойство `required`.

```jsx
<FormItem top="Email" required>
  <Input type="email" name="email" required />
</FormItem>
```

## Удаление поля [#removable]

Добавить возможность удалить поле можно с помощью свойства `removable`,
которое добавит кнопку удаления, стилизованную под используемую платформу.
Помимо значений `true`/`false`, также принимает значение `"indent"`, которое добавляет визуальный отступ,
позволяя выравнивать удаляемые поля с полями, которые удалить нельзя.

При `removable={true}` доступны следующие свойства:

- `removePlaceholder` — текст, который будет зачитан скринридером или показан на платформе iOS
  при взаимодействии с кнопкой удаления (по умолчанию "Удалить");
- `onRemove` — функция-обработчик, которая будет вызвана при нажатии на кнопку удаления.

<Playground>
  ```jsx
  <FormItem
    htmlFor="patronymic"
    removable
    onRemove={() => alert('Обработчик удаления')}
    top="Отчество"
    bottom="Если у вас нет отчества — удалите этот пункт"
    bottomId="patronymicDescription"
  >
    <Input id="patronymic" aria-labelledby="patronymicDescription" />
  </FormItem>
  ```
</Playground>

## Отступы

По умолчанию компонент расставляет внешние отступы, чтобы автоматически выравниваться в соответствии с
требованиями дизайн-системы (при использовании в `Group`, например). Отключить эти отступы можно с помощью свойства `noPadding`.

## Тестирование (e2e) [#e2e]

Для возможности тестирования доступны свойства с постфиксом `*TestId`, которые вы можете использовать,
чтобы находить необходимые части компонента:

- `removeButtonTestId` — `id` кнопки удаления при `removable={true}`;
- `toggleButtonTestId` — `id` кнопки подтверждения удаления (**только для iOS**).

## Доступность (a11y) [#a11y]

Для корректной работы ассистивных технологий необходимо вручную передавать некоторые параметры:

- при передаче в `FormItem` компонента, отвечающего за пользовательский ввод (например, `<input type="text" />`),
  рекомендуется передавать свойства `top` и `htmlFor`. В компонент пользовательского ввода должно быть передано свойство
  `id`, которое соответствует значению `htmlFor` в `FormItem`;
- при использовании свойства `bottom` рекомендуется также передавать в компонент пользовательского ввода (например,
  `<input type="text" />`) свойство `aria-describedby`, а в сам `FormItem` передать `bottomId`,
  который соответствует значению `aria-describedby`.

## Свойства и методы [#api]

<PropsTable name="FormItem">
### FormItem [#form-item-api]

### FormItem.Top [#form-item-top-api]

### FormItem.TopLabel [#form-item-top-label-api]

### FormItem.TopAside [#form-item-top-aside-api]

</PropsTable>
